package cn.billho.popcache.core.impl.redis;

import cn.billho.popcache.core.api.IGlobalLockApi;
import cn.billho.popcache.core.glock.LuaScript;
import io.lettuce.core.ScriptOutputType;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@RequiredArgsConstructor
@Slf4j
public class RedisGlobalLockImpl implements IGlobalLockApi {

    @NonNull
    private StatefulRedisConnection<String,String> mainRedisConnection;

    @Override
    public boolean acquireLock(String key, String value, long expire) {
        String script = LuaScript.LOCK_SCRIPT;
        return execLua(script, key, value, expire) > 0;
    }

    @Override
    public boolean releaseLock(String key, String value) {
        String script = LuaScript.RELEASE_LOCK_SCRIPT;
        return execLua(script, key, value) > 0;
    }

    long execLua(String scrpit, String key, String val){

        RedisCommands<String, String> syncCommands = mainRedisConnection.sync();

        String[] keys = new String[]{key};
        String[] vals = new String[]{val};
        Long result = syncCommands.eval(scrpit, ScriptOutputType.INTEGER, keys, vals);

        // 检查结果
        if (result != null && result == 1) {
            return result;
        } else {
            return 0;
        }
    }

    long execLua(String scrpit, String key, String val, long ttl){

        RedisCommands<String, String> syncCommands = mainRedisConnection.sync();

        String[] keys = new String[]{key};
        String[] vals = new String[]{val,String.valueOf(ttl)};
        Long result = syncCommands.eval(scrpit, ScriptOutputType.INTEGER, keys, vals);

        // 检查结果
        if (result != null && result == 1) {
            return result;
        } else {
            return 0;
        }
    }



}
